// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rbchat.logic.chat_root.impl;

import android.app.Activity;
import android.util.Log;

import com.eva.android.HttpFileDownloadHelper;
import com.eva.android.VoicePlayer;
import com.eva.android.widget.WidgetUtils;
import com.x52im.rbchat.logic.chat_root.AbstractChattingListAdapter;
import com.x52im.rbchat.logic.chat_root.model.Message;
import com.x52im.rbchat.logic.chat_root.sendvoice.SendVoiceHelper;
import com.x52im.rbchat.utils.VoicePlayerEx;

import java.io.File;
import java.util.Observable;
import java.util.Observer;
import com.x52im.rbchat.R;

/**
 * 语音播放器封装实现类.
 *
 * @author Jack Jiang, 2014-02-22
 * @since 2.3
 */
public abstract class VoicePlayerWrapper
{
    private static String TAG = VoicePlayerWrapper.class.getSimpleName();
    private Activity context = null;
    private AbstractChattingListAdapter theChattingListAdater = null;
    private VoicePlayer voicePlayer = null;

    public VoicePlayerWrapper(Activity context, AbstractChattingListAdapter theChattingListAdater) {
        this.context = context;
        this.theChattingListAdater = theChattingListAdater;

        this.voicePlayer = new VoicePlayerEx(context, true);
        // 播放完成时就清除“正在播放”记录
        this.voicePlayer.setOnCompletionObserver(new Observer() {
            @Override
            public void update(Observable observable, Object data) {
                clearPlayingStatus(true);
            }
        });
    }

    protected abstract Message getCurrentVoicePlayingCME();

    protected abstract void setCurrentVoicePlayingCME(Message _currentVoicePlayingCME);

    public void release() {
        // 执行音频的release，释放资源
        voicePlayer.release();
    }

    /**
     * 当前列表单元（语音留言消息）是否处于“播放中”.
     *
     * @param entity
     * @return true表示播放中，否则处于普通状态
     */
    public boolean isEntityVoicePlaying(Message entity) {
//	    return _currentVoicePlayingCME != null && _currentVoicePlayingCME == entity;
        return getCurrentVoicePlayingCME() != null && getCurrentVoicePlayingCME() == entity;
    }

    public void clearPlayingStatus(boolean updateUI) {
        setPlayingStatus(null, updateUI);
    }

    public void setPlayingStatus(Message entity, boolean updateUI) {
//		_currentVoicePlayingCME = entity;
        setCurrentVoicePlayingCME(entity);
        if (updateUI)
            // 通知ui刷新播放状态
            theChattingListAdater.notifyDataSetChangedNotSelectLastLine();
    }

    /**
     * 播放语音留言文件.
     *
     * @param
     * @param entity 对应列表单元数据对象句柄（目前用于收到的消息下载时使用）
     * @return true表示正常进入播放过程，否则表示没有成功（调用者将可以据此来即时恢复”播放中“状态等）
     */
    public boolean playVoice(final Message entity, boolean needDump) {
        boolean sucess = false;
//			if(_currentVoicePlayingCME != null)
        if (getCurrentVoicePlayingCME() != null) {
            // 语音留言消息中的此字段存放的就是语音文件的文件名
//				String voiceFileName = (String)_currentVoicePlayingCME.getText();
            String voiceFileName = (String) getCurrentVoicePlayingCME().getText();
            if (voiceFileName != null) {
                String voiceFilePath = SendVoiceHelper.getSendVoiceSavedDirHasSlash(context) + voiceFileName;
                File voiceFile = new File(voiceFilePath);

                // 音频文件已经存在（收到的或发出的消息）那就直接播放
                if (voiceFile.exists()) {
                    try {
                        voicePlayer.play(voiceFilePath);
                        sucess = true;
                    } catch (Exception e) {
                        WidgetUtils.showToast(context, context.getString(R.string.chat_playvoice_play_faild), WidgetUtils.ToastType.WARN);
                    }
                }
                // 文件不存在
                else {
//                    // true表示是收到的语音留言，否则是发出的语音留言消息
//                    boolean isOutgoing = entity.isOutgoing();
//                    // 发出的消息（文件已不存在，提示一下并退出）
//                    if (isOutgoing) {
//                        WidgetUtils.showToast(context, context.getString(R.string.chat_playvoice_play_faild2), WidgetUtils.ToastType.INFO);
////						// 清空播放状态
////						this.clearPlayingStatus(true);
//                        return false;
//                    }
//                    // 收到的消息（尝试去网络下载）
//                    else
                    {
                        // @since 10.0：本地发出的消息，有可能来自收到的消息的转发，转发的当然就不存在本地缓
                        // 存，所以需要加上这个url以备从网络加载。所以为了达成这一可能，目前发出的（没有转发功
                        // 能以前只读本地缓存文件）和收到的消息，如果本地不存在都可以从网络加载
                        new HttpFileDownloadHelper.DownloadAsyncRoot((Activity) context
                                , SendVoiceHelper.getVoiceDownloadURL(context, voiceFileName, needDump)
                                , SendVoiceHelper.getSendVoiceSavedDir(context)) {
                            @Override
                            protected void onPreExecute() {
                                //
                                entity.getDownloadStatus().setStatus(Message.DownloadStatus.PROCESSING);
                                // 状态的改变同时也通知ui刷新显示哦
                                theChattingListAdater.notifyDataSetChangedNotSelectLastLine();
                            }

                            @Override
                            protected void onProgressUpdate(Integer... progress) {
                                //
                                entity.getDownloadStatus().setProgress(progress[0]);
                                // 状态的改变同时也通知ui刷新显示哦
                                theChattingListAdater.notifyDataSetChangedNotSelectLastLine();
                            }

                            @Override
                            protected void onPostExecute_onSucess(String fileSavedPath) {
                                // 成功下载了语音文件（则播放之）
                                try {
                                    voicePlayer.play(fileSavedPath);

                                    // 设置“播放中”状态（不同于playVoice中的同类方法，因为本代码在
                                    // 内部类中，无法由调用者来决定清空播放状态，所以要自已来干哦）
                                    setPlayingStatus(entity, false); // 异步网络加载完成前，playVoice肯定返回的是false，所以“播放中”状态已被清除，所以此处播放时要设置上去哦
                                    // 设置下载完成状态
                                    entity.getDownloadStatus().setStatus(Message.DownloadStatus.PROCESS_OK);
                                    // 状态的改变同时也通知ui刷新显示哦
                                    theChattingListAdater.notifyDataSetChangedNotSelectLastLine();
                                } catch (Exception e) {
                                    WidgetUtils.showToast(context, context.getString(R.string.chat_playvoice_play_faild3), WidgetUtils.ToastType.WARN);
                                    // 播放失败则清空播放状态（不同于playVoice中的同类方法，因为本代码在
                                    // 内部类中，无法由调用者来决定清空播放状态，所以要自已来干哦）
                                    clearPlayingStatus(true);
                                }
                            }

                            @Override
                            protected void onPostExecute_onException(Exception exception) {
                                WidgetUtils.showToast(context, context.getString(R.string.chat_playvoice_play_faild4), WidgetUtils.ToastType.WARN);
                                entity.getDownloadStatus().setStatus(Message.DownloadStatus.PROCESS_FAILD);
                                // 播放失败则清空播放状态（不同于playVoice中的同类方法，因为本代码在
                                // 内部类中，无法由调用者来决定清空播放状态，所以要自已来干哦）
                                clearPlayingStatus(true);
                            }
                        }.execute();
                    }
                }
            }
            // 要播放的文件名为空？显然是未知原因导致的无效数据
            else {
//					// 清空播放状态
//					this.clearPlayingStatus(true);
            }
        }

        return sucess;
    }

    /**
     * 停止语音播放.
     */
    public void stopVoice() {
        // 播放失败则清空播放状态
//	    AbstractChattingListAdapter.this._currentVoicePlayingCME = null;
        this.clearPlayingStatus(true);

        try {
            voicePlayer.stop();
        } catch (Exception e) {
            Log.w(TAG, e);
        }
    }
}